﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Model.Modules;
using System.Collections.ObjectModel;
using System.Timers;
using System.Configuration;
using Utility;
using Logger = Utility.Logger;
using System.Windows;
using System.Threading;
using EasyModbus;
using Timer = System.Timers.Timer;
using System.ComponentModel;
using Nest;
using System.Diagnostics;
using Elasticsearch.Net;
using System.Xml;
using static ViewModel.VM_PageMonitor;
using Proxy;

namespace ViewModel
{
    class VM_PageMonitor : BaseViewModel
    {

        public ObservableCollection<devicestatus> DeviceStatuslist { get { return deviceStatuslist; } set { deviceStatuslist = value; OnPropertyChanged(); } }
        private ObservableCollection<devicestatus> deviceStatuslist;

        public bool IsExistModbus { get; set; }
        public ObservableCollection<ModbusDeviceInfo> ModbusDeviceStatuslist { get { return modbusDeviceStatuslist; } set { modbusDeviceStatuslist = value; OnPropertyChanged(); } }
        private ObservableCollection<ModbusDeviceInfo> modbusDeviceStatuslist;
        public ObservableCollection<ServiceInfo> ServiceInfolist { get { return serviceInfolist; } set { serviceInfolist = value; OnPropertyChanged(); } }
        private ObservableCollection<ServiceInfo> serviceInfolist;

        public bool IsRefershing { get { return isRefershing; } set { isRefershing = value; OnPropertyChanged(); } }
        private bool isRefershing;

        public bool IsAdmin
        {
            get { return StaticData.IsAdmin; }
            set
            {
                if (value)
                {
                    VM_WindowPassWord vm = new VM_WindowPassWord();
                    vm.ShowDialog();
                    var psd = new surfacedetectEntities().sysconfig.Where(t => t.key == "adminpsd").FirstOrDefault().value;
                    if ((vm.UIElement as Window).DialogResult == false || vm.PassWord != psd)
                    {

                        MessageBox("密码不正确");
                        return;
                    }
                }
                StaticData.IsAdmin = value;
                OnPropertyChanged();
            }
        }


        public bool ModbusOnline
        {
            get { return modbusOnline; }
            set
            {
                modbusOnline = value; OnPropertyChanged();
                ModbusDeviceStatuslist.All((modbusdevice) =>
                {
                    modbusdevice.ConnectStatus = value;
                    return true;
                });
            }
        }
        private bool modbusOnline;

        private ModbusClient modbusclient;

        public Object maxtemp;
        string statusStr;
        public string StatusStr
        {
            get { return statusStr; }
            set
            {
                statusStr = value;
                //try
                //{
                //    Random r = new Random();
                //    var list = JsonConvert.DeserializeObject<List<devicestatus>>(statusStr);
                //    foreach (var item in list)
                //    {
                //        if (item.temperature > 200)
                //            item.temperature = r.Next(250, 265) / 10.0f;
                //    }
                //    DeviceStatuslist = new ObservableCollection<devicestatus>(list);

                //    StaticData.Temperature = list.Where(t => t.temperature < 200).Average(t => t.temperature);
                //}
                //catch (Exception e)
                //{
                //    Logger.Error(e);
                //}
            }
        }

        string wssaddress = ConfigurationManager.AppSettings["wssaddress"];
        static surfacedetectEntities mysqldb = new surfacedetectEntities();

        public VM_PageMonitor()
        {

            InitData();

        }

        private void InitData()
        {
            IsRefershing = false;
            ModbusOnline = false;
            ModbusDeviceStatuslist = new ObservableCollection<ModbusDeviceInfo>();
            DeviceStatuslist = new ObservableCollection<devicestatus>();
            ServiceInfolist = new ObservableCollection<ServiceInfo>();
            initServiceInfo();
            initModebusDevice();

            for (int i = 1; i <= 10; i++)
            {
                DeviceStatuslist.Add(new devicestatus() { devicename =  i.ToString(),  connection = true});
            }
            //StaticData.Temperature = 25;

            Timer timer = new Timer(5000);
            timer.Elapsed += (sender, e) =>
            {
                //判断ServiceInfolist中的Status是否有false
                bool isAllOk = ServiceInfolist.All(t => t.Status);
                if (IsRefershing|| !isAllOk)
                {
                    _ = refreshServiceStatus();
                    refreshModbusDeviceStatus();

                }
            };
            timer.Start();
        }


        private void initModebusDevice()
        {
            var modbusinfos = (XmlElement)SysConfig.GetInstance().SelectSingleNode("/sysconfig/view/PageMonitor/modbuslist");
            if((modbusinfos as XmlElement).GetAttribute("isExist")=="false")
                IsExistModbus= false;
            else
                IsExistModbus = true;
            if(!IsExistModbus)
                return;

            foreach (var modbusinfo in modbusinfos)
            {
                var modbus = modbusinfo as XmlElement;
                ModbusDeviceInfo modbusDevice = new ModbusDeviceInfo
                {
                    Point = int.Parse(modbus.GetAttribute("point")),
                    Name = modbus.GetAttribute("Name"),
                    Status = false,
                    ConnectStatus = false
                };
                ModbusDeviceStatuslist.Add(modbusDevice);
            }

            var ip = System.Configuration.ConfigurationManager.AppSettings["lightingip"];
            var port = int.Parse(System.Configuration.ConfigurationManager.AppSettings["lightingport"]);
            modbusclient = new EasyModbus.ModbusClient(ip, port);
            try
            {
                modbusclient.Connect();
                ModbusDeviceStatuslist.All((modbusdevice) =>
                {
                    setModBusDeviceStatus(modbusdevice.Point, true);
                    return true;
                });
            }
            catch (EasyModbus.Exceptions.ConnectionException e)
            {
                Logger.Error("Modbus无法连接", e);
            }
            ModbusOnline = modbusclient.Connected ? true : false;
            refreshModbusDeviceStatus();

        }

        private void initServiceInfo()
        {
            ServiceInfolist = new ObservableCollection<ServiceInfo>();
            var serverinfos=(XmlElement)SysConfig.GetInstance().SelectSingleNode("/sysconfig/view/PageMonitor/serverlist");
            foreach (var serverinfo in serverinfos)
            {
                var server = serverinfo as XmlElement;
                ServiceInfo serviceInfo = new ServiceInfo
                {
                    id = int.Parse(server.GetAttribute("id")),
                    IPAddress = server.GetAttribute("IPAddress"),
                    Name = server.GetAttribute("Name"),
                    Status=false
                };
                ServiceInfolist.Add(serviceInfo);
            }
            //_ = InitWSclient();
            _ = refreshServiceStatus();
        }
        private async Task refreshServiceStatus()
        {
            await Task.Run(new Action(() =>
            {
                foreach (var item in ServiceInfolist)
                {
                    switch (item.id)
                    {
                        case 0://控制服务
                            item.Status = NetWorkHelper.PingOk(item.IPAddress);
                            break;
                        case 1://采集服务
                            item.Status = NetWorkHelper.PingOk(item.IPAddress);
                            break;
                        case 2://检测服务
                            item.Status = NetWorkHelper.PingOk(item.IPAddress);
                            break;
                        case 3://基础信息数据库
                            item.Status = mysqldb.Database.Exists();
                            break;
                        case 4://缺陷图像数据库
                            item.Status = NetWorkHelper.TelnetOk(item.IPAddress, 9200);
                            break;
                        default:
                            break;
                    }

                }
            }));
        }

        private void refreshModbusDeviceStatus()
        {
            if (!IsExistModbus)
                return;
            if (modbusclient.Connected)
            {
                foreach (var item in ModbusDeviceStatuslist)
                {
                    var result = modbusclient.ReadCoils(item.Point, 1);
                    item.Status = result[0];
                }
            }
            else
            {
                ModbusOnline = false;
            }
        }


        public BaseCommand ChangeStatusCmd
        {
            get => new BaseCommand((obj) =>
            {
                var modinfo = (obj as ModbusDeviceInfo);
                //modinfo.Status = !modinfo.Status;
                setModBusDeviceStatus(modinfo.Point, modinfo.Status);

            });
        }
        public BaseCommand GradeConfigCommand { get => new BaseCommand(GradeConfigCommand_Executed); }
        public void GradeConfigCommand_Executed(object obj)
        {
            new VM_WindowGradeConfig().ShowDialog();
        }

        public BaseCommand DefectTypeConfigCommand { get => new BaseCommand(DefectTypeConfigCommand_Executed); }
        public void DefectTypeConfigCommand_Executed(object obj)
        {
            new VM_WindowConfig().ShowDialog();
        }
        public BaseCommand SysConfigCommand { get => new BaseCommand(SysConfigCommand_Executed); }

        private void SysConfigCommand_Executed(object obj)
        {
            new VM_WindowSysConfig().ShowDialog();
        }
        public BaseCommand AdminCommand
        {
            get => new BaseCommand((obj) =>
            {
                VM_WindowPassWord vm = new VM_WindowPassWord();
                vm.ShowDialog();
                if ((vm.UIElement as Window).DialogResult == true)
                {
                    if (vm.PassWord == "")
                    {
                        StaticData.IsAdmin = true;
                    }
                }
            });
        }



        private void setModBusDeviceStatus(int address, bool value)
        {
            modbusclient.WriteSingleCoil(address, value);
        }

        public class ModbusDeviceInfo : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;

            public int Point { get; set; }
            public string Name { get; set; }
            public bool Status { get; set; }
            public bool ConnectStatus { get; set; }
        }
        public class ServiceInfo : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;

            public int id { get; set; }
            public string IPAddress { get; set; }
            public int Port { get; set; }
            public string Name { get; set; }
            public bool Status { get; set; }

        }



    }
}
